use serde::{Deserialize, Serialize};
use std::hash::Hash;

// 定义PageRequest trait
pub trait PageRequest {
    // 获取页码
    fn get_page_number(&self) -> usize;
    // 获取页面大小
    fn get_page_size(&self) -> usize;
    fn get_sort(&self)->&Sort;
    // 创建上一页的PageRequest
    // 创建下一页的PageRequest
    fn next(&self) -> Box<dyn PageRequest>;

    // 创建第一页的PageRequest
    fn first(&self) -> Box<dyn PageRequest> {
        self.with_page(1)
    }

    // 根据页码创建新的PageRequest
    fn with_page(&self, page_number: usize) -> Box<dyn PageRequest>;

    // 获取Sort，需要Sort trait的具体实现
    fn with_sort(&self) -> Option<Box<Sort>>;

    // 检查是否有前一页
    fn has_previous(&self) -> bool;
}

// 实现PageRequest trait的一个示例
pub struct PageRequestImpl {
    page_number: usize,
    page_size: usize,
    sort: Sort,
}

impl PageRequestImpl {
    pub fn new(page_number: usize, page_size: usize, sort: Sort) -> Self {
        PageRequestImpl {
            page_number,
            page_size,
            sort,
        }
    }
}

impl PageRequest for PageRequestImpl {
    fn get_page_number(&self) -> usize {
        self.page_number
    }

    fn get_page_size(&self) -> usize {
        self.page_size
    }

    fn get_sort(&self)->&Sort{
        &self.sort
    }
    fn next(&self) -> Box<dyn PageRequest> {
        todo!()
    }

    fn with_page(&self, page_number: usize) -> Box<dyn PageRequest> {
        todo!()
    }

    fn with_sort(&self) -> Option<Box<Sort>> {
        todo!()
    }

    fn has_previous(&self) -> bool {
        todo!()
    }

    // 其他方法的实现...
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
pub enum Direction {
    Asc,
    Desc,
}

impl Default for Direction {
    fn default() -> Self {
        Direction::Asc
    }
}

impl Direction {
    pub fn from_string(s: &str) -> Direction {
        match s.to_lowercase().as_str() {
            "asc" => Direction::Asc,
            "desc" => Direction::Desc,
            _ => Direction::Asc,
        }
    }
    pub fn is_descending(&self) -> bool {
        self == &Direction::Desc
    }
    pub fn is_ascending(&self) -> bool {
        self == &Direction::Asc
    }
}

#[derive(Debug, Serialize, Deserialize, Clone, Default, Eq, PartialEq, Hash)]
pub struct Order {
    pub direction: Direction,
    pub property: String,
}

impl Order {
    pub fn new(direction: Direction, property: String) -> Self {
        Order {
            direction,
            property,
        }
    }

    pub fn reverse(&self) -> Self {
        Order {
            direction: if self.direction == Direction::Asc {
                Direction::Desc
            } else {
                Direction::Asc
            },
            property: self.property.clone(),
        }
    }

    pub fn by(property: String) -> Self {
        Order {
            direction: Sort::DEFAULT_DIRECTION,
            property,
        }
    }

    pub fn asc(property: String) -> Self {
        Order {
            direction: Direction::Asc,
            property,
        }
    }

    pub fn desc(property: String) -> Self {
        Order {
            direction: Direction::Desc,
            property,
        }
    }

    pub fn with(&self, direction: Direction) -> Self {
        Order {
            direction,
            property: self.property.clone(),
        }
    }
}

#[derive(Debug, Serialize, Deserialize, Clone, Default, Eq, PartialEq, Hash)]
pub struct Sort {
    pub orders: Vec<Order>,
}

impl Sort {
    // Define the Direction static block equivalent in Rust
    const DEFAULT_DIRECTION: Direction = Direction::Asc;
    pub fn new(orders: Vec<Order>) -> Self {
        Sort { orders }
    }

    pub fn by(properties: Vec<String>, direction: Direction) -> Self {
        if properties.is_empty() {
            return Sort::unsorted();
        }
        let orders = properties
            .into_iter()
            .map(|prop| Order::new(direction.clone(), prop))
            .collect();
        Sort::new(orders)
    }

    pub fn by_any(orders: Vec<(String, Direction)>) -> Self {
        if orders.is_empty() {
            return Sort::unsorted();
        }
        let orders = orders
            .into_iter()
            .map(|prop| Order::new(prop.1, prop.0))
            .collect();
        Sort::new(orders)
    }

    pub fn unsorted() -> Self {
        Sort { orders: vec![] }
    }

    pub fn descending(&self) -> Self {
        todo!() // Implement descending method
    }

    pub fn ascending(&self) -> Self {
        todo!() // Implement ascending method
    }

    pub fn is_sorted(&self) -> bool {
        !self.orders.is_empty()
    }

    pub fn is_empty(&self) -> bool {
        self.orders.is_empty()
    }

    pub fn is_unsorted(&self) -> bool {
        !self.is_sorted()
    }

    pub fn and(&self, other: &Sort) -> Sort {
        let mut combined_orders = self.orders.clone();
        combined_orders.extend(other.orders.clone());
        Sort::new(combined_orders)
    }

    pub fn reverse(&self) -> Sort {
        todo!() // Implement reverse method
    }

    pub fn get_order_for(&self, property: &str) -> Option<&Order> {
        self.orders.iter().find(|order| order.property == *property)
    }

    // todo!: Implement iterator method for Order

    pub fn equals(&self, other: &Sort) -> bool {
        //  other.orders
        let mut i = 0;
        for ele in &self.orders {
            if ele != &other.orders[i] {
                return false;
            }
            i += 1;
        }
        return true;
    }

    pub fn with_direction(&self, direction: Direction) -> Self {
        let mut vec = Vec::with_capacity(self.orders.len());
        for order in self.orders.clone() {
            vec.push(order.with(direction.clone()));
        }
        Sort { orders: vec }
    }
}
